package com.niguang.work.api.weChatTemplate;


import com.alibaba.fastjson.JSONObject;
import com.niguang.common.constant.ResultCode;
import com.niguang.common.pojo.Result;
import com.niguang.common.util.HttpClientUtil;
import com.niguang.common.util.SignUtil;
import com.niguang.work.api.weChatTemplate.vo.WeChatSignVo;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.WxMpUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotNull;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Enumeration;
import java.util.Map;
import java.util.UUID;

/**
 * 微信签名
 */
@RestController
@RequestMapping("/wechat/")
@Slf4j
public class WeChatSign {

    @Resource
    private WxMpService wxService;


    @Value("${wechat.mp.appId}")
    private String appId;


    /**
     * 监听微信事件
     *
     * @param request
     * @return
     */
    @PostMapping("monitorEvent")
    public String monitorEvent(HttpServletRequest request) {
        try {
            Enumeration enu = request.getParameterNames();
            while (enu.hasMoreElements()) {
                String paraName = (String) enu.nextElement();
                log.info("监听事件请求参数：{}", paraName + ": " + request.getParameter(paraName));
            }

            // 微信加密签名
            String signature = request.getParameter("signature");
            // 时间戳
            String timestamp = request.getParameter("timestamp");
            // 随机数
            String nonce = request.getParameter("nonce");
            // 随机字符串
            String echostr = request.getParameter("echostr");

            // 通过检验signature对请求进行校验，若校验成功则原样返回echostr，表示接入成功，否则接入失败
            if (SignUtil.checkSignature(signature, timestamp, nonce)) {
                return echostr;
            }
            log.info("签名检验失败：{}", signature);
        } catch (Exception e) {
            log.error("微信监听事件异常：", e);
        }
        return "";

    }


    /**
     * 获取微信签名
     *
     * @param signUrl
     * @return
     */
    @GetMapping("getSign")
    public Result getSign(@NotNull @RequestParam String signUrl) {
        try {
            signUrl = URLDecoder.decode(signUrl, "utf-8");
            String accessToken = wxService.getAccessToken();
            String xml = HttpClientUtil.get("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="
                    + accessToken + "&type=jsapi");
            Map jsonMap = JSONObject.parseObject(xml, Map.class);
            if (!StringUtils.equalsIgnoreCase(jsonMap.get("errcode").toString(), "0")) {
                return Result.build(ResultCode.SERVICE_UNAVAILABLE, "获取微信{accessToken}失效，前端参数获取失败！");
            }
            String jsapi_ticket = (String) jsonMap.get("ticket");
            // 获取签名signature
            String nonce = UUID.randomUUID().toString();
            String timestamp = Long.toString(System.currentTimeMillis() / 1000);
            String str = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonce + "&timestamp=" + timestamp + "&url="
                    + signUrl;
            String signature = SHA1(str);
            if (StringUtils.isBlank(signature)) {
                return Result.build(ResultCode.SERVICE_UNAVAILABLE, "微信签名获取错误！");
            }
            WeChatSignVo weChatSignVo = new WeChatSignVo(signature, timestamp, nonce, appId);
            log.info("微信签名参数：{}", weChatSignVo);
            return Result.build(ResultCode.SUCCESS, "签名获取成功！", weChatSignVo);
        } catch (Exception e) {
            log.error("微信签名失败：{}", e);
        }
        return Result.failed();

    }


    /**
     * @description： SHA、SHA1加密 @parameter： str：待加密字符串 @return： 加密串
     **/
    public static String SHA1(String str) {
        try {
            // 如果是SHA加密只需要将"SHA-1"改成"SHA"即可
            MessageDigest digest = java.security.MessageDigest.getInstance("SHA-1");
            digest.update(str.getBytes());
            byte messageDigest[] = digest.digest();
            // Create Hex String
            StringBuffer hexStr = new StringBuffer();
            // 字节数组转换为 十六进制 数
            for (int i = 0; i < messageDigest.length; i++) {
                String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
                if (shaHex.length() < 2) {
                    hexStr.append(0);
                }
                hexStr.append(shaHex);
            }
            return hexStr.toString();

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }


    public static void main(String[] args) {
        try {
            String redirectURI1 = URLEncoder.encode("https://www.gzhuijiangyuan.com/wechat/api/wechatUser/toWechatPage?dev=2", "UTF-8");
            String scope = "snsapi_userinfo"; // snsapi_base
            String state = "110";
            String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx03b5a85713ee6e13&redirect_uri="
                    + redirectURI1 + "&response_type=code&scope=" + scope + "&state=100#wechat_redirect";


            // https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx03b5a85713ee6e13&redirect_uri=https%3A%2F%2Fwww.gzhuijiangyuan.com%2Fwechat%2Fapi%2FwechatUser%2FtoWechatPage&response_type=code&scope=snsapi_userinfo&state=100&connect_redirect=1#wechat_redirect
            System.out.println(url);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
